﻿using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using Microsoft.MediaPlayer.Interop;
using BMproductions.Media.MediaPlayer.WMPPlus.Properties;

namespace BMproductions.Media.MediaPlayer.WMPPlus {
	[Guid("A5D0DDBE-4316-4E8F-A66E-DCD5F9D870B4")]
	//[Guid("5FA68D2D-062E-4C61-856D-53B388F9FA16")]
	[ProgId("WMPPlus.WMPPlus"), ComVisible(true), Singleton]
	public class WMPPlus: WMPPlusPublic {
		public const string FriendlyName = "WMPPlus.NET";
		public const int MaxSupportedVersion = 11;

		public override string CurrentFolder {
			get {
				string path = WMPPlusCore.GetStrProp(WMPPlusProperty.MediaFolder);
				if (path != this.currentFolder) {
					this.currentFolder = path;
					this.currentMedia = null;
				}
				return path;
			}
		}
		public override IWMPMedia CurrentMedia {
			get {
				string path = WMPPlusCore.GetStrProp(WMPPlusProperty.MediaFolder);
				if (path != this.currentFolder) {
					this.currentFolder = path;
					this.currentMedia = null;
				}
				if (this.currentMedia == null && this.currentFolder != null) {
					this.currentMedia = LoadMedia(this.currentFolder);
					if (this.currentMedia == null) {
						WMPPlusCore.SetStrProp(WMPPlusProperty.MediaFolder, null);
					}
				}
				return this.currentMedia;
			}
		}
		public WMPMenu Menu { get; private set; }
		public object/*WMPMSN*/ MSN {get; private set; }
		public WMPUIAddons Addons { get; private set; }
		public object/*WMPFileContext*/ FileContext { get; private set; }
		public object/*WMPTagEditor*/ TagEditor { get; private set; }
		public object/*WMPAdvancedPlayback*/ Playback { get; private set; }
		public object/*WMPStateRestore*/ StateRestore { get; private set; }
		public object/*WMPPartyShuffle*/ PartyShuffle { get; private set; }
		public object/*WMPHotkeys*/ Hotkeys { get; private set; }
		public IntPtr LibraryMenu {
			get { return WMPPlusCore.GetPtrProp(WMPPlusProperty.LibMenu); }
		}

		[DllImport(WMPPlusPublic.WMPPlusHookName, EntryPoint = "#103")]
		private static extern void WMPPlusInitialize(out IntPtr menu);
		[DllImport(WMPPlusPublic.WMPPlusHookName, EntryPoint = "#104")]
		private static extern void WMPPlusDispose();

		public static WMPPlus Plugin { get; private set; }

		[ComRegisterFunction]
		static void RegisterWMPPlus(Type type) {
			string assm = FriendlyName;
			string path = Path.Combine(Path.GetDirectoryName(typeof(WMPPlus).Assembly.Location), WMPPlusPublic.WMPPlusHookName);
			WMPHookShared.RegisterHook(assm, path);
			var prod = (System.Reflection.AssemblyDescriptionAttribute[])typeof(WMPPlus).Assembly.GetCustomAttributes(typeof(System.Reflection.AssemblyDescriptionAttribute), true);
			string label, desc;
			if (Environment.OSVersion.Version.Major >= 6) {
				label = "res://WMPPlusHook.dll/RT_STRING/#1001";
				desc = "res://WMPPlusHook.dll/RT_STRING/#1002";
			} else {
				label = Resources.PluginFriendlyName;
				desc = Resources.PluginDescription;
			}
			WMPPlugEvents.RegisterUIPlugin(typeof(WMPPlus).GUID,
				prod != null && prod.Length != 0 ? prod[0].Description : assm,
				label, desc,
				(int)(PluginFlags.PLUGIN_FLAGS_HASPROPERTYPAGE | PluginFlags.PLUGIN_FLAGS_INSTALLAUTORUN | PluginFlags.PLUGIN_FLAGS_LAUNCHPROPERTYPAGE) |
				(int)(PluginType.PLUGIN_TYPE_BACKGROUND));
		}

		[ComUnregisterFunction]
		static void UnregisterWMPPlus(Type type) {
			string assm = FriendlyName;
			WMPPlugEvents.UnregisterUIPlugin(typeof(WMPPlus).GUID);
			WMPHookShared.UnregisterHook(assm);
		}

		public WMPPlus() {
			//core = new WMPPlusCore();
			//className = "Windows Media Player Plus!";
			Settings = null;
			//HookFolder = false;
			Menu = null;
			MSN = null;
			Addons = null;
			FileContext = null;
			TagEditor = null;
			StateRestore = null;
		}

		protected override void Init() {
			lock (typeof(WMPPlus)) {
				Plugin = this;
			}
			base.Init();
			currentFolder = null;
			currentMedia = null;
			Settings = new WMPPlusSettings();
			if (WMPlayerVersion != Settings[WMPPlusSettings.NumberNames.LastUnsupportedVersion] &&
				WMPlayerVersion < MaxSupportedVersion) {
				string msg = String.Format(Resources.ErrorUnsupportedVersion, Resources.PluginFriendlyName, MaxSupportedVersion);
				MessageBox.Show(null/*WMPlayerWindow*/, msg, Resources.PluginFriendlyName, MessageBoxButtons.OK, MessageBoxIcon.Error);
				Settings[WMPPlusSettings.NumberNames.LastUnsupportedVersion] = WMPlayerVersion;
				Settings.SaveSettings();
			}
			if (WMPPlusCore.Hook.Libraries == 0) {
				string msg = String.Format(Resources.ErrorInstallCorrupted, Resources.PluginFriendlyName);
				MessageBox.Show(null/*WMPlayerWindow*/, msg, Resources.PluginFriendlyName, MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			//TODO: WMPPlusCore.sub_53F828();
			WMPPlusCore.Plugins.Init();
			IntPtr menu;
			WMPPlusInitialize(out menu);
			Menu = new WMPMenu(this, menu);
			//TODO: MSN = new WMPMSN(this);
			Addons = new WMPUIAddons(this, Menu);
			//TODO: FileContext = new WMPFileContext(this, Menu);
			//TODO: TagEditor = new WMPTagEditor(this, Menu);
			//TODO: Playback = new WMPAdvancedPlayback(this, Menu);
			//TODO: StateRestore = new WMPStateRestore(this);
			//TODO: PartyShuffle = new WMPPartyShuffle(this, StateRestore);
			//TODO: Hotkeys = new WMPHotkeys(this);
			//TODO: StateRestore.sub_4C29E4();
			//TODO: HotkeysCore.sub_4CABB4();
		}

		public override void Dispose() {
			base.Dispose();
			Hotkeys = null;
			StateRestore = null;
			PartyShuffle = null;
			TagEditor = null;
			MSN = null;
			Addons.Free();
			Addons = null;
			FileContext = null;
			Menu.Free();
			Menu = null;
			//TODO: WMPPlusCore.sub_53F854();
			Settings.SaveSettings();
			Settings.Free();
			Settings = null;
			WMPPlusDispose();
			WMPPlusCore.Dispose();
			lock (typeof(WMPPlus)) {
				Plugin = null;
			}
		}

		IWMPMedia LoadMedia(string path) {
			IWMPPlaylist list = this.core.mediaCollection.getByAttribute("SourceURL", path);
			if (list.count < 1) return null;
			return list.Item[0];
		}

		#region IWMPPluginUI implementation
		public override HResult DisplayPropertyPage(IntPtr hwndParent) {
			base.DisplayPropertyPage();
			return HResult.S_OK;
		}
		#endregion

		#region IWMPEvents implementation
		public override void PlayStateChange(int NewState) {
			switch ((WMPPlayState)NewState) {
			case WMPPlayState.wmppsStopped:
			case WMPPlayState.wmppsWaiting:
				//TODO: WMPPlusCore.MediaHook.f38 = false;
				break;
			}
			if (Addons != null)
				Addons.PlayStateChange(NewState);
			//TODO: if (MSN != null)
			//TODO: 	MSN.PlayStateChange(NewState);
			//TODO: if (Playback != null)
			//TODO: 	Playback.PlayStateChange(NewState);
		}

		public override void MediaChange(object Item) {
			if (Addons != null)
				Addons.MediaChange(Item);
			//TODO: if (MSN != null)
			//TODO: 	MSN.MediaChange(Item);
		}

		public override void CurrentItemChange(object pdispMedia) {
			//TODO: if (Playback != null)
			//TODO: 	Playback.CurrentItemChange(pdispMedia);
			//TODO: if (PartyShuffle != null)
			//TODO: 	PartyShuffle.CurrentItemChange(pdispMedia);
		}

		public override void CurrentPlaylistChange(WMPPlaylistChangeEventType change) {
			//TODO: if (PartyShuffle != null)
			//TODO: 	PartyShuffle.CurrentPlaylistChange(change);
		}
		#endregion
	}
}
